"""
Класс контекста сообщения.
Класс события нового сообщения

Author: Milinuri Nirvalen
"""

from .ui import Logger

import time


class Context:
	def __init__(self, app, backend=None, event={}):
		'''вспомогательный класс для вызываемых функций
		:param app: экземпляр Чио
		:optional param backend: экземпляр движка
		:optional param event: экземпляр события'''

		self.app = app
		self.backend = backend
		self.event = event

		# описание времени
		self.now = self.event.get('date', int(time.time()))
		self.minutes = round(self.now/60)*60
		self.strtime = time.ctime(self.now)

	async def message(self, message, **params):
		'''функция отправки сообщения
		:param message: текст сообщения
		:param **params: дополнительные передоваемые переметры

		:return: API ответ'''

		# если не указана точка назначения --> id чата из события
		if 'peer_id' not in params:
			params['peer_id'] = self.event.get('to.id')
		return await self.backend.message(self.event, message, **params)

	async def request(self, method, **params):
		'''отправка API запроса
		: param method   :  названия API метода
		: param **params : дополнительно передаваемые перемтры

		: return : {"error":bool:, "response":dict}'''
		return await self.backend.request(method, **params)

	async def upload_photo(self, file=None, b=None, peer_id=None):
		'''метод загрузки фотографии
		: param file    :  путь до файла
		: param b       :  bytes переменная изображения
		: param peer_id :  точка назначения

		: return :  API ответ'''
		return await self.backend.upload_photo(file, b, peer_id)


class Event:
	__slots__ = ("model")

	def __init__(self, model={}):
		"""класс события
		:optional param model: словарь своей модели события"""

		self.model = model or {
			'from':{
				'id':0,
				'is_mechanism':False,
				'first_name':'',
				'last_name':'',
				'username':'',
				'is_admin':False,
				},
			'to':{
				'is_chat':False,
				'id':0,
				'is_admin':False},
			'id':0,
			'level':1,
			'attachs':[],
			'reply':{},
			'date':0,
			'text':'',
			'action':{},
			'raw':None}


	def get(self, param, value=None):
		'''метод получения параметра модели
		пример:
		get("a.b") = event.model["a"]["b"]

		:param param: название переметра 1.2.3
		:optional param value: возвращаемое значени при отцуцтвии параметра

		:return: например 1.2, значение 2, если не найдено, 1 или value'''

		params = param.split('.')
		temp = self.model.get(params[0])

		for p in params[1:]:
			if type(temp) == dict:
				temp = temp.get(p)

		return temp or value


	def merge(self, target, model=None):
		'''метод совмещения словаря с self.model
		:param target: словарь, который необходимо совместить
		:optional param model: начальный словарь для совмещения, или self.model'''
		if not model:
			model = self.model

		for k, v in target.items():
			if k in model:
				if type(v) == dict and type(model[k]) == dict:
					self.merge(v, model[k])
			model[k] = v


	def replaceParam(self, index, key, value):
		'''метод замены параметра словаря
		пример:
		get("a.b", c) = indexl["a"]["b"] = c

		:param index: словарь, для которого необходимо произвести изменения
		:param key: ключи словаря 1.2.3
		:param value: значени для замены

		:return: изменённый словарь'''
		if isinstance(key, str):
			keys = key.split('.')
		else:
			keys = key

		for x in keys:
			keys.pop(0)

			if x not in index:
				if keys:
					index[x] = {}
				else:
					index[x] = value

			if keys:
				index[x] = self.replaceParam(index[x], keys, value)
			else:
				index[x] = value

		return index


	def set(self, param, arg):
		'''обёртка метода replaceParam для self.model
		:param param: ключи словаря 1.2.3
		:param value: значени для замены'''
		self.model = self.replaceParam(self.model, param, arg)
